﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Entity_Framework_Lab1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with Query Expressions *****\n");
            // Test Array!!
            ProductInfo[] itemsInStock = new[] { 
            new ProductInfo{ Name = "Mac's Coffee", Description = "Coffee with TEETH", NumberInStock = 24}, 
            new ProductInfo{ Name = "Milk Maid Milk", Description = "Milk cow's love", NumberInStock = 100}, 
            new ProductInfo{ Name = "Pure Silk Tofu", Description = "Bland as Possible", NumberInStock = 120}, 
            new ProductInfo{ Name = "Cruchy Pops", Description = "Cheezy, peppery goodness", NumberInStock = 2}, 
            new ProductInfo{ Name = "RipOff Water", Description = "From the tap to your wallet", NumberInStock = 100}, 
            new ProductInfo{ Name = "Classic Valpo Pizza", Description = "Everyone loves pizza!", NumberInStock = 73}};

            //SelectEverything(itemsInStock); //Visar ALLT!
            //ListProductNames(itemsInStock); //Listar bara namnen.
            //GetOverstock(itemsInStock); //Listar produkter som har stock över 25.
            //GetNamesAndDescriptions(itemsInStock); //Ger namn och description
            //GetProjectedSubsetCall(itemsInStock); //Returnerar en array med namn och beskrivning till metoden som sen loopar och listar igenom den.
            //GetCountFromQuery(); //Skriver ut hur många i listan vars namn är längre än 6 tecken.
            //ReverseEverything(itemsInStock); //Listar hela itemsInStock baklänges.
            //AlphabetizeProductNames(itemsInStock); //Skriver ut iteminstock i bokstavsordning.
            //DisplayDiff(); //Jämför två listor och skriver ut det den ena har men inte den andra.
            //DisplayIntersection(); //Skriver ut det de två listorna har gemensamt
            //DisplayUnion(); //Sätter ihop båda listorna, lika saker kopieras inte över?
            //DisplayConcat(); //sätter ihop båda listorna och skriver ut det, men nu kopieras dubletter över också.
            //DisplayConcatNoDups(); //Sätter ihop båda listorna, med dubletter. Men .distinct gör att endast unika skrivs ut.
            //AggregateOps(); //Summerar, ger average, min och max på en lista.




            Console.ReadLine();

        }

        private static void GetProjectedSubsetCall(ProductInfo[] itemsInStock)
        {
            Array objs = GetProjectedSubset(itemsInStock);
            foreach (object o in objs)
            {
                Console.WriteLine(o);
            }
        }
        static void SelectEverything(ProductInfo[] products)
        {
            Console.WriteLine("All product details:");
            var allProducts = from p in products select p;
            foreach (var prod in allProducts)
            {
                Console.WriteLine(prod.ToString());
            }
        }

        static void ListProductNames(ProductInfo[] products)
        {
            Console.WriteLine("Only product names:");
            var names = from p in products select p.Name;
            foreach (var n in names)
            {
                Console.WriteLine("Name: {0}", n);
            }
        }

        static void GetOverstock(ProductInfo[] products)
        {
            Console.WriteLine("The overstock items!");
            var overstock = from p in products where p.NumberInStock > 25 select p;
            foreach (ProductInfo c in overstock)
            {
                Console.WriteLine(c.ToString());
            }
        }

        static void GetNamesAndDescriptions(ProductInfo[] products)
        {
            Console.WriteLine("Names and Descriptions:");
            var nameDesc = from p in products select new { p.Name, p.Description };
            foreach (var item in nameDesc)
            {
                Console.WriteLine(item.ToString());
            }
        }

        static Array GetProjectedSubset(ProductInfo[] products)
        {
            var nameDesc = from p in products select new { p.Name, p.Description };
            return nameDesc.ToArray();
        }

        static void GetCountFromQuery()
        {
            string[] currentVideoGames = {"Morrowind", "Uncharted 2", 
            "Fallout 3", "Daxter", "System Shock 2"};
            int numb =
            (from g in currentVideoGames where g.Length > 6 select g).Count();
            Console.WriteLine("{0} items honor the LINQ query.", numb);
        }

        static void ReverseEverything(ProductInfo[] products)
        {
            Console.WriteLine("Product in reverse:");
            var allProducts = from p in products select p;
            foreach (var prod in allProducts.Reverse())
            {
                Console.WriteLine(prod.ToString());
            }
        }

        static void AlphabetizeProductNames(ProductInfo[] products)
        {
            var subset = from p in products orderby p.Name select p;
            Console.WriteLine("Ordered by Name:");
            foreach (var p in subset)
            {
                Console.WriteLine(p.ToString());
            }
        }

        static void DisplayDiff()
        {
            List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW" };
            List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" };
            var carDiff = (from c in myCars select c)
            .Except(from c2 in yourCars select c2);
            Console.WriteLine("Here is what you don't have, but I do:");
            foreach (string s in carDiff)
                Console.WriteLine(s);
        }
        
        static void DisplayIntersection()
        {
            List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW" };
            List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" };
            var carIntersect = (from c in myCars select c)
            .Intersect(from c2 in yourCars select c2);
            Console.WriteLine("Here is what we have in common:");
            foreach (string s in carIntersect)
                Console.WriteLine(s);
        }
        
        static void DisplayUnion()
        {
            List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW" };
            List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" };
            var carUnion = (from c in myCars select c)
            .Union(from c2 in yourCars select c2);
            Console.WriteLine("Here is everything:");
            foreach (string s in carUnion)
                Console.WriteLine(s);
        }

        static void DisplayConcat()
        {
            List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW" };
            List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" };
            var carConcat = (from c in myCars select c)
            .Concat(from c2 in yourCars select c2);
            foreach (string s in carConcat)
                Console.WriteLine(s);
        }
        
        static void DisplayConcatNoDups()
        {
            List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW" };
            List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" };
            var carConcat = (from c in myCars select c)
            .Concat(from c2 in yourCars select c2);
            foreach (string s in carConcat.Distinct())
                Console.WriteLine(s);
        }

        static void AggregateOps()
        {
            double[] winterTemps = { 2.0, -21.3, 8, -4, 0, 8.2 };
            Console.WriteLine("Max temp: {0}",
            (from t in winterTemps select t).Max());
            Console.WriteLine("Min temp: {0}",
            (from t in winterTemps select t).Min());
            Console.WriteLine("Avarage temp: {0}",
            (from t in winterTemps select t).Average());
            Console.WriteLine("Sum of all temps: {0}",
            (from t in winterTemps select t).Sum());
        } 
    }

    class ProductInfo
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public int NumberInStock { get; set; }
        public override string ToString()
        {
            return string.Format("Name={0}, Description={1}, Number in Stock={2}",
            Name, Description, NumberInStock);
        }
    }
}
